﻿using Advantech.Motion;
using BZ.Core.TaskExt;
using BZ.Logger;
using BZVision;
using HalconDotNet;
using NDK.Frm;
using NDK.Module.DAL;
using NDK.Module.Model;
using NDK.Module.StationLogic;
using NDK.Motion.BLL;
using NDK.Motion.MachineManager;
using NDK.Motion.StationLogic;
using NDK.Motion.Sys;
using NDK.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Input;


namespace NDK.Module.BLL
{
    public enum DBType
    {
        String, Bool, Int, Double
    }

    class PublicMethod
    {

        public static log4net.ILog m_Logger1 = log4net.LogManager.GetLogger("PublicMethod");

        #region 按钮状态属性
        private static bool? _BtnStop;

        public static bool? BtnStop
        {
            get { return _BtnStop; }
            set
            {
                if (_BtnStop != value)
                {
                    _BtnStop = value;
                    if (value == false)
                    {
                        Pause();
                    }
                    Common.OmronPLC.Write(Common.PLCAdr.DicOutPutBool[PLCOutPutBool.停止], (bool)value);
                }
            }
        }

        private static bool? _BtnInit;

        public static bool? BtnInit
        {
            get { return _BtnInit; }
            set
            {
                if (_BtnInit != value)
                {
                    _BtnInit = value;
                    if (value == true)
                    {
                        Intial();
                    }
                    Common.OmronPLC.Write(Common.PLCAdr.DicOutPutBool[PLCOutPutBool.复位], (bool)value);
                }
            }
        }

        private static bool? _BtnStart;

        public static bool? BtnStart
        {
            get { return _BtnStart; }
            set
            {
                if (_BtnStart != value)
                {
                    _BtnStart = value;
                    if (value == true && SwManualAuto == true)
                    {
                        Start();
                    }
                    Common.OmronPLC.Write(Common.PLCAdr.DicOutPutBool[PLCOutPutBool.启动], (bool)value);
                    //Common.OmronPLC.Write(Common.PLCAdr.DicOutPutBool[PLCOutPutBool.复位], false);
                    Common.OmronPLC.Write(Common.PLCAdr.DicOutPutBool[PLCOutPutBool.停止], false);
                }
            }
        }

        private static bool? _SwManualAuto;

        public static bool? SwManualAuto
        {
            get { return _SwManualAuto; }
            set
            {
                _SwManualAuto = value;
                if (value == false)
                {
                    Pause();
                }
                Common.OmronPLC.Write(Common.PLCAdr.DicOutPutBool[PLCOutPutBool.手自动], (bool)value);
            }
        }

        #endregion

        /// <summary>
        /// 每次启动得到最新的数据
        /// </summary>
        public static void UpdateRuningData()
        {
            Type type = typeof(Common);
            var parms = type.GetFields();
            var strings = parms.Where(x => x.Name.Contains("SP_")).ToArray();
            var doubles = parms.Where(x => x.Name.Contains("DP_")).ToArray();
            var ints = parms.Where(x => x.Name.Contains("IP_")).ToArray();
            var bools = parms.Where(x => x.Name.Contains("BP_")).ToArray();

            UpdataDBData(DBType.Bool, ref bools);
            UpdataDBData(DBType.String, ref strings);
            UpdataDBData(DBType.Int, ref ints);
            UpdataDBData(DBType.Double, ref doubles);

            if (!Common.GRR循环模式)
            {
                var holeShield = parms.Where(x => x.Name.Contains("BP_转盘穴")).ToArray();
                for (int i = 0; i < holeShield.Length; i++)
                {
                    Common.DicHoleShield[i + 1] = (bool)holeShield[i].GetValue(null);
                }
            }
            Machine.MachineResourceInit();

            Common.AppendUiLog.Log("参数更新完成", LogType.Info);

            void UpdataDBData(DBType dbType, ref FieldInfo[] fields)
            {
                DataSet ds = null;
                switch (dbType)
                {
                    case DBType.String:
                        {
                            bool ishave = false;
                            ds = new StringParamServices().GetList("");
                            for (int i = 0; i < fields.Length; i++)
                            {
                                string name = fields[i].GetCustomAttribute<DescriptionAttribute>().Description;
                                foreach (DataRow item in ds.Tables[0].Rows)
                                {
                                    if (item[1].ToString() == name)
                                    {
                                        ishave = true;
                                        fields[i].SetValue(null, Convert.ChangeType(item[2], fields[i].FieldType));
                                        break;
                                    }
                                }
                                if (!ishave)
                                {
                                    new StringParamServices().Add(new StringParam()
                                    {
                                        ID = i,
                                        字符串值 = "",
                                        参数名称 = strings[i].GetCustomAttribute<DescriptionAttribute>().Description
                                    });
                                }
                                ishave = false;
                            }
                        }
                        break;
                    case DBType.Bool:
                        {
                            bool ishave = false;
                            ds = new BoolParamServices().GetList("");
                            for (int i = 0; i < fields.Length; i++)
                            {
                                string name = fields[i].GetCustomAttribute<DescriptionAttribute>().Description;
                                foreach (DataRow item in ds.Tables[0].Rows)
                                {
                                    if (item[1].ToString() == name)
                                    {
                                        ishave = true;
                                        fields[i].SetValue(null, Convert.ChangeType(item[2], fields[i].FieldType));
                                    }
                                }
                                if (!ishave)
                                {
                                    new BoolParamServices().Add(new BoolParam()
                                    {
                                        ID = i,
                                        布尔值 = false,
                                        参数名称 = bools[i].GetCustomAttribute<DescriptionAttribute>().Description
                                    });
                                }
                                ishave = false;
                            }
                        }
                        break;
                    case DBType.Int:
                        {
                            bool ishave = false;
                            ds = new IntParamServices().GetList("");
                            for (int i = 0; i < fields.Length; i++)
                            {
                                string name = fields[i].GetCustomAttribute<DescriptionAttribute>().Description;
                                foreach (DataRow item in ds.Tables[0].Rows)
                                {
                                    if (item[1].ToString() == name)
                                    {
                                        ishave = true;
                                        fields[i].SetValue(null, Convert.ChangeType(item[2], fields[i].FieldType));
                                    }
                                }
                                if (!ishave)
                                {
                                    new IntParamServices().Add(new IntParam()
                                    {
                                        ID = i,
                                        整型值 = 0,
                                        最大值 = 9999,
                                        最小值 = -9999,
                                        参数名称 = ints[i].GetCustomAttribute<DescriptionAttribute>().Description
                                    });
                                }
                                ishave = false;
                            }
                        }
                        break;
                    case DBType.Double:
                        {
                            bool ishave = false;
                            ds = new FloatParamServices().GetList("");
                            for (int i = 0; i < fields.Length; i++)
                            {
                                string name = fields[i].GetCustomAttribute<DescriptionAttribute>().Description;
                                foreach (DataRow item in ds.Tables[0].Rows)
                                {
                                    if (item[1].ToString() == name)
                                    {
                                        ishave = true;
                                        fields[i].SetValue(null, Convert.ChangeType(item[2], fields[i].FieldType));
                                    }
                                }
                                if (!ishave)
                                {
                                    new FloatParamServices().Add(new FloatParam()
                                    {
                                        ID = i,
                                        浮点值 = 0,
                                        最大值 = 9999,
                                        最小值 = -9999,
                                        参数名称 = doubles[i].GetCustomAttribute<DescriptionAttribute>().Description
                                    });
                                }
                                ishave = false;
                            }
                        }
                        break;
                }
            }
        }


        public static void NewDBParms()
        {
            var stringParm = new StringParamServices();
            var doubleParm = new FloatParamServices();
            var intParm = new IntParamServices();
            var boolParm = new BoolParamServices();

            Type type = typeof(Common);
            var parms = type.GetFields();
            var strings = parms.Where(x => x.Name.Contains("SP_")).ToList();
            var doubles = parms.Where(x => x.Name.Contains("DP_")).ToList();
            var ints = parms.Where(x => x.Name.Contains("IP_")).ToList();
            var bools = parms.Where(x => x.Name.Contains("BP_")).ToList();

            for (int i = 0; i < strings.Count; i++)
            {
                stringParm.Add(new StringParam()
                {
                    ID = i,
                    字符串值 = "",
                    参数名称 = strings[i].GetCustomAttribute<DescriptionAttribute>().Description
                });
            }

            for (int i = 0; i < doubles.Count; i++)
            {
                doubleParm.Add(new FloatParam()
                {
                    ID = i,
                    浮点值 = 0,
                    最大值 = 9999,
                    最小值 = -9999,
                    参数名称 = doubles[i].GetCustomAttribute<DescriptionAttribute>().Description
                });
            }

            for (int i = 0; i < bools.Count; i++)
            {
                boolParm.Add(new BoolParam()
                {
                    ID = i,
                    布尔值 = false,
                    参数名称 = bools[i].GetCustomAttribute<DescriptionAttribute>().Description
                });
            }

            for (int i = 0; i < ints.Count; i++)
            {
                intParm.Add(new IntParam()
                {
                    ID = i,
                    整型值 = 0,
                    最大值 = 9999,
                    最小值 = -9999,
                    参数名称 = ints[i].GetCustomAttribute<DescriptionAttribute>().Description
                });
            }
        }

        #region 复位，启动，暂停状态变化
        public static void Intial()
        {
            if (MachineStatusManager.CurrentMachineStatus == MachineStatus.Initialized)//整机复位
            {
                if (SwManualAuto == true)
                {
                    Common.AppendUiLog.Log("点击复位...", LogType.Info);
                    MachineStatusManager.CurrentMachineStatus = MachineStatus.Homing;
                }
                return;
            }
            else if (MachineStatusManager.CurrentMachineStatus == MachineStatus.Alarm)//报警复位
            {
                Common.AppendUiLog.Log("点击复位...", LogType.Info);

                if (MachineStatusManager.LastMachineStatus == MachineStatus.Running)//如果报警前处于运行状态，报警复位后转到暂停状态
                {
                    MachineStatusManager.CurrentMachineStatus = MachineStatus.Pause;
                }
                else//否则恢复上次的状态
                {
                    MachineStatusManager.CurrentMachineStatus = MachineStatusManager.LastMachineStatus;
                }
                return;
            }
            else if (MachineStatusManager.CurrentMachineStatus == MachineStatus.Pause)//报警复位
            {
                Common.AppendUiLog.Log("点击复位...", LogType.Info);

                if (MachineStatusManager.LastMachineStatus == MachineStatus.Homing)//如果报警前处于运行状态，报警复位后转到暂停状态
                {
                    MachineStatusManager.CurrentMachineStatus = MachineStatusManager.LastMachineStatus;
                }
                return;
            }
        }
        public static void Start()
        {
            if ((MachineStatusManager.CurrentMachineStatus == MachineStatus.Ready || MachineStatusManager.CurrentMachineStatus == MachineStatus.Pause) && MachineStatusManager.CurrentMachineStatus != MachineStatus.Running)
            {
                foreach (var axis in MachineDataManager.Instance.AxisList)
                {
                    axis.IsStop = false;
                }
                MachineStatusManager.CurrentMachineStatus = MachineStatus.Running;
                Common.AppendUiLog.Log("开始运行...", LogType.Info);
            }
        }
        public static void Pause()
        {
            try
            {
                if (MachineStatusManager.CurrentMachineStatus == MachineStatus.Running || MachineStatusManager.CurrentMachineStatus == MachineStatus.Homing)
                {
                    Common.AppendUiLog.Log("点击暂停...", LogType.Info);
                    MachineStatusManager.CurrentMachineStatus = MachineStatus.Pause;
                    foreach (var axis in MachineDataManager.Instance.AxisList)
                    {
                        axis.IsStop = true;
                    }

                    Common.AppendUiLog.Log("暂停中...", LogType.Info);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace);
            }
        }
        public static void Stop()
        {
            if (MachineStatusManager.CurrentMachineStatus == MachineStatus.Running || MachineStatusManager.CurrentMachineStatus == MachineStatus.Pause
              || MachineStatusManager.CurrentMachineStatus == MachineStatus.Emerg || MachineStatusManager.CurrentMachineStatus == MachineStatus.Alarm
              || MachineStatusManager.CurrentMachineStatus == MachineStatus.Ready || MachineStatusManager.CurrentMachineStatus == MachineStatus.Homing)
            {
                Common.CT.Stop();
                Common.AppendUiLog.Log("点击停止...", LogType.Info);
                foreach (var axis in MachineDataManager.Instance.AxisList)
                {
                    axis.IsStop = true;
                }
                if (MachineStatusManager.CurrentMachineStatus == MachineStatus.Homing)//回零状态下等待停止状态回复
                {
                    foreach (var axis in MachineDataManager.Instance.AxisList)
                    {
                        while (axis.IsStop == true)
                        {
                            Thread.Sleep(100);
                        }
                    }
                }

                foreach (var axis in MachineDataManager.Instance.AxisList)//保证板卡资源释放，才能关闭工站线程，否则抛异常
                {
                    axis.WaitMoveDone();
                }
                MachineStatusManager.CurrentMachineStatus = MachineStatus.Stopping;

                //Thread.Sleep(2000);
                Common.AppendUiLog.Log("停止中...", LogType.Info);
                StationManager.StationList.ForEach(s =>
                {
                    s?.Stop();
                });
                StationManager.StationList.Clear();
                TaskManager.StopAll();

                Common.AppendUiLog.Log("已停止！", LogType.Alert);
                MachineStatusManager.CurrentMachineStatus = MachineStatus.Initialized;
                foreach (var axis in MachineDataManager.Instance.AxisList)
                {
                    axis.IsStop = false;
                }
            }
        }
        #endregion


        #region 三色灯控制线程函数
        public static void ThreadMethod_TriColorLamp()
        {
            bool IsAlarm = false;
            while (true)
            {
                if (Common.isCardInitialed)
                {
                    try
                    {
                        IsAlarm = false;
                        switch (MachineStatusManager.CurrentMachineStatus)
                        {
                            case MachineStatus.Unknown://红灯闪烁
                                {
                                    IsAlarm = true;
                                    Machine.do_红灯.Toggle();
                                    Machine.do_黄灯.OFF();
                                    Machine.do_绿灯.OFF();

                                    Machine.do_启动按钮灯.OFF();
                                    Machine.do_停止按钮灯.OFF();
                                    Machine.do_复位按钮灯.OFF();
                                }
                                break;
                            case MachineStatus.Running://绿灯亮
                                {
                                    Machine.do_红灯.OFF();
                                    Machine.do_黄灯.OFF();
                                    Machine.do_绿灯.ON();

                                    Machine.do_启动按钮灯.ON();
                                    Machine.do_停止按钮灯.OFF();
                                    Machine.do_复位按钮灯.OFF();
                                }
                                break;
                            case MachineStatus.Pause://黄灯亮
                                {
                                    Machine.do_红灯.OFF();
                                    Machine.do_黄灯.ON();
                                    Machine.do_绿灯.OFF();

                                    Machine.do_启动按钮灯.OFF();
                                    Machine.do_停止按钮灯.ON();
                                    Machine.do_复位按钮灯.OFF();
                                }
                                break;
                            case MachineStatus.Initialized:
                                {
                                    Machine.do_红灯.OFF();
                                    Machine.do_黄灯.Toggle();
                                    Machine.do_绿灯.OFF();

                                    Machine.do_启动按钮灯.OFF();
                                    Machine.do_停止按钮灯.OFF();
                                    Machine.do_复位按钮灯.Toggle();
                                }
                                break;
                            case MachineStatus.Homing://黄灯闪烁
                                {
                                    Machine.do_红灯.OFF();
                                    Machine.do_黄灯.Toggle();
                                    Machine.do_绿灯.OFF();

                                    Machine.do_启动按钮灯.OFF();
                                    Machine.do_停止按钮灯.OFF();
                                    Machine.do_复位按钮灯.ON();
                                }
                                break;
                            case MachineStatus.Ready://绿灯闪烁
                                {
                                    Machine.do_红灯.OFF();
                                    Machine.do_黄灯.OFF();
                                    Machine.do_绿灯.Toggle();

                                    Machine.do_启动按钮灯.Toggle();
                                    Machine.do_停止按钮灯.OFF();
                                    Machine.do_复位按钮灯.OFF();
                                }
                                break;
                            case MachineStatus.Alarm:
                            case MachineStatus.Emerg://红灯闪烁，蜂鸣器闪烁
                                {
                                    IsAlarm = true;
                                    Machine.do_红灯.Toggle();
                                    Machine.do_黄灯.OFF();
                                    Machine.do_绿灯.OFF();

                                    Machine.do_启动按钮灯.OFF();
                                    Machine.do_停止按钮灯.Toggle();
                                    Machine.do_复位按钮灯.OFF();
                                }
                                break;
                            case MachineStatus.Quit://退出，关闭三色灯和蜂鸣器
                                {
                                    Machine.do_红灯.OFF();
                                    Machine.do_黄灯.OFF();
                                    Machine.do_绿灯.OFF();
                                    Machine.do_蜂鸣器.OFF();

                                    Machine.do_启动按钮灯.OFF();
                                    Machine.do_停止按钮灯.OFF();
                                    Machine.do_复位按钮灯.OFF();
                                }
                                return;
                            default:
                                break;
                        }

                        if (Common.BP_启用蜂鸣器)
                        {
                            if (IsAlarm || Common.Alarm_PLC轻报警 || Common.Alarm_PLC重报警)
                            {
                                Machine.do_蜂鸣器.Toggle();
                            }
                            else
                            {
                                Machine.do_蜂鸣器.OFF();
                            }
                        }
                        else
                        {
                            Machine.do_蜂鸣器.OFF();
                        }
                    }
                    catch (Exception ex)
                    {
                        MachineStatusManager.CurrentMachineStatus = MachineStatus.Alarm;
                        Common.AppendUiLog.Log("三色灯 线程扫描异常！", LogType.Error);
                        m_Logger1.Error(ex.StackTrace);
                        return;
                    }
                }

                Thread.Sleep(500);
            }
        }
        #endregion


        public static void ThreadMethod_Home()
        {
            while (MachineStatusManager.CurrentMachineStatus != MachineStatus.Quit)
            {
                if (MachineStatusManager.CurrentMachineStatus == MachineStatus.Homing && Common.isCardInitialed == true)
                {
                    try
                    {
                        SafeDoorWork(true);
                        HomeBefore();

                        int ret = MotionControl.HomeAllAxis();
                        if (ret == 0) //轴回零
                        {
                            HomeAfer();

                            MachineStatusManager.CurrentMachineStatus = MachineStatus.Ready;
                            Common.AppendUiLog.Log("设备整机复位完成！", LogType.Alert);
                            UpdateRuningData();
                        }
                        else
                        {
                            if (ret == 1)//超时
                            {
                                Common.AppendUiLog.Log("轴回零超时！", LogType.Error);
                                MessageBox.Show("轴回零超时，不能启动");
                                MachineStatusManager.CurrentMachineStatus = MachineStatus.Initialized;
                            }
                            if (ret == 2)
                            {
                                Common.AppendUiLog.Log("轴回零过程中，暂停！", LogType.Error);
                                MessageBox.Show("轴回零过程中，暂停");
                                MachineStatusManager.CurrentMachineStatus = MachineStatus.Initialized;
                            }
                            if (ret == 3)
                            {
                                Common.AppendUiLog.Log("轴回零过程中，掉使能！", LogType.Error);
                                MessageBox.Show("轴回零过程中，掉使能");
                                MachineStatusManager.CurrentMachineStatus = MachineStatus.Initialized;
                            }
                            if (ret == 4)
                            {
                                Common.AppendUiLog.Log("轴回零控制失败！", LogType.Error);
                                MessageBox.Show("轴回零控制失败");
                                MachineStatusManager.CurrentMachineStatus = MachineStatus.Initialized;
                            }

                        }
                    }
                    catch (Exception ex)
                    {
                        MachineStatusManager.CurrentMachineStatus = MachineStatus.Alarm;
                        Common.AppendUiLog.Log($"轴回零异常！{ex.Message}", LogType.Error);
                        m_Logger1.Error(ex.StackTrace);
                    }
                }
                Thread.Sleep(10);
            }
        }

        private static void HomeBefore()
        {
            //string msg = string.Empty;
            //bool isTrue = true;
            StringBuilder str;
            var inputFields = MachineDataManager.Instance.DIList.FindAll(x => x.Name.Contains("真空检测"));
            do
            {
                str = new StringBuilder();
                foreach (var item in inputFields)
                {
                    var re = item.GetStatus();
                    str.Append(re ? $"{item.Name}\r\n" : string.Empty);
                }

                if (!string.IsNullOrEmpty(str.ToString()))
                {
                    MessageBox.Show($"检查各个气缸和检测平台是否有料\r\n {str.ToString()}", "提示",
                                     MessageBoxButtons.OK,
                                     MessageBoxIcon.Information,
                                     MessageBoxDefaultButton.Button1,
                                     MessageBoxOptions.DefaultDesktopOnly);
                }
            } while (!string.IsNullOrEmpty(str.ToString()));

            var outFields = MachineDataManager.Instance.DOList.FindAll(x => x.Name.Contains("真空"));
            outFields.ForEach(x => x.OFF());

            bool isok = true;
            while (isok)
            {
                if (!Common.PLCAdr.DicInPutValue[PLCInPut.上料安全信号] || !Common.PLCAdr.DicInPutValue[PLCInPut.下料安全信号])
                {
                    MessageBox.Show($"检查上下料机械手是否安全位\r\n", "提示",
                                         MessageBoxButtons.OK,
                                         MessageBoxIcon.Information,
                                         MessageBoxDefaultButton.Button1,
                                         MessageBoxOptions.DefaultDesktopOnly);
                }
                else
                {
                    isok = false;
                }

                Thread.Sleep(10);
            }
            //while (isTrue)
            //{

            //msg = "";
            //Thread.Sleep(10);
            //if (Machine.di_转盘真空检测1.GetStatus())
            //{
            //    msg += "转盘一穴有料" + "\r\n";
            //}
            //if (Machine.di_转盘真空检测2.GetStatus())
            //{
            //    msg += "转盘二穴有料" + "\r\n";
            //}
            //if (Machine.di_转盘真空检测3.GetStatus())
            //{
            //    msg += "转盘三穴有料" + "\r\n";
            //}
            //if (Machine.di_转盘真空检测4.GetStatus())
            //{
            //    msg += "转盘四穴有料" + "\r\n";
            //}
            //if (Machine.di_转盘真空检测5.GetStatus())
            //{
            //    msg += "转盘五穴有料" + "\r\n";
            //}
            //if (Machine.di_转盘真空检测6.GetStatus())
            //{
            //    msg += "转盘六穴有料" + "\r\n";
            //}
            //if (Machine.di_转盘真空检测7.GetStatus())
            //{
            //    msg += "转盘七穴有料" + "\r\n";
            //}
            //if (Machine.di_转盘真空检测8.GetStatus())
            //{
            //    msg += "转盘八穴有料" + "\r\n";
            //}
            //if (Machine.di_转盘下料真空检测1.GetStatus() && Machine.di_转盘下料真空检测2.GetStatus())
            //{
            //    msg += "转盘下料工位有料" + "\r\n";
            //}
            //if (Machine.di_下料搬运真空检测1.GetStatus() && Machine.di_下料搬运真空检测2.GetStatus())
            //{
            //    msg += "移载工位有料" + "\r\n";
            //}
            //if (Machine.di_翻转真空检测1.GetStatus() && Machine.di_翻转真空检测2.GetStatus())
            //{
            //    msg += "翻转工位有料" + "\r\n";
            //    //}
            //    if (!string.IsNullOrEmpty(msg))
            //    {
            //        MessageBox.Show($"检查各个气缸和检测平台是否有料，请人工确认此花篮的信息\r\n {msg}", "提示",
            //                         MessageBoxButtons.OK,
            //                         MessageBoxIcon.Information,
            //                         MessageBoxDefaultButton.Button1,
            //                         MessageBoxOptions.DefaultDesktopOnly);
            //    }
            //    else
            //    {
            //        isTrue = false;
            //    }
            //}
            //Machine.do_转盘真空吸1.OFF(); Machine.do_转盘真空吸2.OFF(); Machine.do_转盘真空吸3.OFF(); Machine.do_转盘真空吸4.OFF();
            //Machine.do_转盘真空吸5.OFF(); Machine.do_转盘真空吸6.OFF(); Machine.do_转盘真空吸7.OFF(); Machine.do_转盘真空吸8.OFF();
            //Machine.do_转盘下料真空吸1.OFF(); Machine.do_转盘下料真空吸2.OFF(); Machine.do_翻转真空吸1.OFF(); Machine.do_翻转真空吸2.OFF();

        }

        private static void HomeAfer()
        {
            MotionControl.AxesMove(Machine.pos_转盘初始位_转盘旋转);
            MotionControl.AxesMove(Machine.pos_激光扫描安全位_转盘工位六);
            //Common.OmronPLC.Write(Common.PLCAdr.DicOutPutBool[PLCOutPutBool.PC远程控制PLC],true);
            if(Common.CurProType == "Product")
            {
                foreach (var item in Common.PLCAdr.DicOutPutBool.Keys)
                {
                    Common.OmronPLC.Write(Common.PLCAdr.DicOutPutBool[item], false);
                    Common.OmronPLC.Write(Common.PLCAdr.DicOutPutBool[PLCOutPutBool.PC远程控制PLC], true);

                }
            }
           
            #region 光源
            foreach (var lightController in MachineDataManager.Instance.LightControllerList)
            {
                if (lightController.IsConnect == false)
                {
                    lightController.Connect();
                }
                lightController.CloseAllLight();
            }
            #endregion

            #region 工位初始化
            Station_上料定位.Instance.Init();
            Station_转盘一穴.Instance.Init();
            Station_转盘二穴.Instance.Init();
            Station_转盘三穴.Instance.Init();
            Station_转盘四穴.Instance.Init();
            Station_转盘五穴.Instance.Init();
            Station_转盘六穴.Instance.Init();
            Station_转盘七穴.Instance.Init();
            Station_转盘八穴.Instance.Init();
            Station_量测转盘.Instance.Init();
            Station_转盘下料.Instance.Init();
            Station_下置激光.Instance.Init();
            Station_产品扫码.Instance.Init();
            Station_下料搬运.Instance.Init();
            Station_PPG测量.Instance.Init();
            Station_下料翻转.Instance.Init();
            #endregion
        }



        #region 机台左侧按钮扫描线程函数：停止、复位、启动
        /// <summary>
        /// 机台按钮扫描线程函数：停止、复位、启动
        /// </summary>
        /// 

        public static void ThreadMethod_ScanButton()
        {
            while (MachineStatusManager.CurrentMachineStatus != MachineStatus.Quit)
            {
                if (Common.isCardInitialed == true)
                {
                    try
                    {
                        BtnStop = MachineDataManager.Instance.SYS_DI_Pause?.GetStatus();
                        BtnInit = MachineDataManager.Instance.SYS_DI_Reset?.GetStatus();
                        BtnStart = MachineDataManager.Instance.SYS_DI_Start?.GetStatus();//按下启动，弹开停止
                        SwManualAuto = Machine.di_手自动按钮.GetStatus();
                    }
                    catch (Exception ex)
                    {
                        if (AlarmPause("IO扫描异常", "按钮IO扫描异常", "点击确定，再试一次；点击取消，重启软件，检查板卡是否掉线", "再试一次", "重启软件，检查板卡") == DialogResult.Cancel)
                        {
                            //Stop();
                            //Common.isCardInitialed = false;
                        }
                    }
                }
                Thread.Sleep(200);
            }
        }

        #endregion

        #region 停机报警
        public static DialogResult AlarmPause(string title, string excMsg, string exSolution, string okOperationTip, string cancelOperationTip)
        {
            MachineStatusManager.CurrentMachineStatus = MachineStatus.Alarm;
            Common.AppendUiLog.Log(excMsg + exSolution, LogType.Error);

            DateTime startTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));


            DialogResult dr = MessageBox.Show(excMsg + Environment.NewLine
                + "【原因(解决方案)】" + exSolution + Environment.NewLine
                + "【确定】" + okOperationTip + Environment.NewLine
                + "【取消】" + cancelOperationTip, title, MessageBoxButtons.OKCancel);

            if (dr == DialogResult.OK)
            {
                excMsg += ",点击【确定】" + okOperationTip;
            }
            else
            {
                excMsg += ",点击【取消】" + cancelOperationTip;
            }


            DateTime endTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss").ToString());

            int timeCount = (endTime - startTime).Seconds;

            AlarmInfo alarmInfo = new AlarmInfo()
            {
                StartTime = startTime,
                EndTime = endTime,
                TimeCount = timeCount,
                Type = title,
                Description = excMsg
            };

            AlarmInfoServices AlarmInfoServices = new AlarmInfoServices();
            AlarmInfoServices.Add(alarmInfo);

            return dr;

        }
        public static DialogResult AlarmPause(string title, string excMsg, string exSolution, string okOperationTip)
        {
            MachineStatusManager.CurrentMachineStatus = MachineStatus.Alarm;
            Common.AppendUiLog.Log(excMsg + exSolution, LogType.Error);

            DateTime startTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

            DialogResult dr = MessageBox.Show(excMsg + Environment.NewLine
               + "【原因(解决方案)】" + exSolution + Environment.NewLine
               + "【确定】" + okOperationTip + Environment.NewLine,
               title, MessageBoxButtons.OK);

            if (dr == DialogResult.OK)
            {
                excMsg += ",点击【确定】" + okOperationTip;
            }


            DateTime endTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss").ToString());

            int timeCount = (endTime - startTime).Seconds;

            AlarmInfo alarmInfo = new AlarmInfo()
            {
                StartTime = startTime,
                EndTime = endTime,
                TimeCount = timeCount,
                Type = title,
                Description = excMsg
            };

            AlarmInfoServices AlarmInfoServices = new AlarmInfoServices();
            if (alarmInfo.Type != "IO读写异常")
            {
                AlarmInfoServices.Add(alarmInfo);
            }

            return dr;

        }
        public static DialogResult AlarmPause(string title, string excMsg, string exSolution, string yesOperationTip, string noOperationTip, string cancelOperationTip)
        {
            MachineStatusManager.CurrentMachineStatus = MachineStatus.Alarm;
            Common.AppendUiLog.Log(excMsg + exSolution, LogType.Error);

            DateTime startTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));


            DialogResult dr = MessageBox.Show(excMsg + Environment.NewLine
                + "【原因(解决方案)】" + exSolution + Environment.NewLine
                + "【是】" + yesOperationTip + Environment.NewLine
                + "【否】" + noOperationTip + Environment.NewLine
                + "【取消】" + cancelOperationTip,
                title, MessageBoxButtons.YesNoCancel);

            if (dr == DialogResult.Yes)
            {
                excMsg += ",点击【是】" + yesOperationTip;
            }
            else if (dr == DialogResult.No)
            {
                excMsg += ",点击【否】" + noOperationTip;
            }
            else
            {
                excMsg += ",点击【取消】" + cancelOperationTip;
            }

            DateTime endTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss").ToString());

            int timeCount = (endTime - startTime).Seconds;

            AlarmInfo alarmInfo = new AlarmInfo()
            {
                StartTime = startTime,
                EndTime = endTime,
                TimeCount = timeCount,
                Type = title,
                Description = excMsg
            };

            AlarmInfoServices AlarmInfoServices = new AlarmInfoServices();
            AlarmInfoServices.Add(alarmInfo);

            return dr;

        }
        #endregion

        #region 扫描轴运动状态的函数
        /// <summary>
        /// 扫描轴运动状态的函数
        /// </summary>
        public static void ThreadMethod_AxisStatus()
        {
            bool isRun = true;
            while (MachineStatusManager.CurrentMachineStatus != MachineStatus.Quit && isRun)
            {
                Thread.Sleep(100);
                if (Common.isCardInitialed == false)
                {
                    continue;
                }
                //检测轴报警
                string txt_MotorAlarmNo = string.Empty;

                foreach (var axis in MachineDataManager.Instance.AxisList)
                {
                    try
                    {
                        if (axis.GetAlarm() == true)
                        {
                            DialogResult dr = AlarmPause("轴报警", "轴[" + axis.Name + "]电机报警",
                                      "手动清除报警后重新打开软件，或点击确定尝试自动清除报警！", "尝试自动清除报警", "手动清除，重启软件", "不检查轴报警");
                            if (dr == DialogResult.Yes)
                            {
                                try
                                {
                                    axis.ClearAlarm();
                                }
                                catch { }
                                Thread.Sleep(500);
                            }
                            else if (dr == DialogResult.No)
                            {
                                try
                                {
                                    MotionControl.AllAxisServoOff();
                                }
                                catch { }

                                //记录软件关闭时间
                                DateTime startTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

                                DateTime endTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

                                TimeSpan ts = endTime - startTime;
                                int timeCount = (int)ts.TotalSeconds;
                                AlarmInfo alarmInfo = new AlarmInfo()
                                {
                                    StartTime = startTime,
                                    EndTime = endTime,
                                    TimeCount = timeCount,
                                    Type = "轴报警",
                                    Description = axis.Name + "报警," + ""
                                };

                                AlarmInfoServices AlarmInfoServices = new AlarmInfoServices();
                                AlarmInfoServices.Add(alarmInfo);

                                StopMachine();
                                Application.Exit();
                                Environment.Exit(-1);//直接退出不提示
                            }
                            else
                            {
                                isRun = false;
                                break;
                            }
                        }
                    }
                    catch (Exception) { }
                }
            }
        }
        #endregion

        #region 机台控制方法：StopMachine，PauseMachine，AwakeMachine
        public static void StopMachine()
        {
            PauseMachine();

            MotionControl.AllAxisServoOff();
            foreach (var card in MachineDataManager.Instance.CardList)
            {
                //关闭卡片
                if (card?.Initialized == true)
                {
                    card.Finalize();
                }
            }
        }
        private static void PauseMachine()
        {
            Common.CT.Stop();
            foreach (var axis in MachineDataManager.Instance.AxisList)
            {
                axis.IsStop = true;
            }
        }
        #endregion

        #region 监控EMG线程
        public static void ThreadMethod_EMGStatus()
        {
            while (MachineStatusManager.CurrentMachineStatus != MachineStatus.Quit)
            {
                //设备状态显示
                Frm_Main.Instance.lbl_Status.Text = MachineStatusManager.CurrentMachineStatus.ToString();
                if (MachineStatusManager.CurrentMachineStatus == MachineStatus.Unknown || MachineStatusManager.CurrentMachineStatus == MachineStatus.Alarm)
                {
                    Frm_Main.Instance.lbl_Status.BackColor = Color.Red;
                }
                else if (MachineStatusManager.CurrentMachineStatus == MachineStatus.Running)
                {
                    Frm_Main.Instance.lbl_Status.BackColor = Color.Green;
                }
                else
                {
                    Frm_Main.Instance.lbl_Status.BackColor = Color.Yellow;
                }

                Thread.Sleep(10);
            }
        }
        #endregion

        #region 安全门开关
        public static event Action<bool> SafeDoorWorkAction;

        public static void SafeDoorWork(bool isopen)
        {
            if (isopen)
            {
                Machine.do_安全门1.ON();
                Machine.do_安全门2.ON();
                Machine.do_安全门3.ON();
                Machine.do_安全门4.ON();
                Machine.do_安全门5.ON();
                Machine.do_安全门6.ON();
            }
            else
            {
                Machine.do_安全门1.OFF();
                Machine.do_安全门2.OFF();
                Machine.do_安全门3.OFF();
                Machine.do_安全门4.OFF();
                Machine.do_安全门5.OFF();
                Machine.do_安全门6.OFF();
            }

            SafeDoorWorkAction?.Invoke(isopen);
        }
        #endregion

        #region 监控门信号线程
        public static void ThreadMethod_DoorStatus()
        {
            while (MachineStatusManager.CurrentMachineStatus != MachineStatus.Quit)
            {
                if (Common.isCardInitialed == true)
                {
                    if (Common.BP_启用安全门)
                    {

                    }
                }
                Thread.Sleep(200);
            }
        }
        #endregion

        #region 公共方法

        /// <summary>
        /// 截屏
        /// </summary>
        public static void CaptureScreen()
        {
            //屏幕宽
            int userWidth = Screen.PrimaryScreen.Bounds.Width;
            //屏幕高
            int userHeight = Screen.PrimaryScreen.Bounds.Height;
            //按照屏幕宽高创建位图
            Image img = new Bitmap(userWidth, userHeight);
            //从一个继承自Image类的对象中创建Graphics对象
            Graphics gc = Graphics.FromImage(img);
            //抓屏并拷贝到myimage里
            gc.CopyFromScreen(new System.Drawing.Point(0, 0), new System.Drawing.Point(0, 0), new System.Drawing.Size(userWidth, userHeight));
            //this.BackgroundImage = img;
            //保存位图
            string fileNameExt = "Capture_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".jpg";//文件名
            string path = Application.StartupPath + @"\Log\CaptureScreen\" + fileNameExt;
            img.Save(path);
        }

        #region 点云转real图片
        public static bool PointsToRealImage(out HObject Image, HTuple width, HTuple height, List<double> pointList)
        {
            Image = new HObject();
            if (width <= 0 || height <= 0)
            {
                return false;
            }
            if (pointList == null || pointList.Count <= 0)
            {
                return false;
            }
            HTuple rowSequence = new HTuple();
            HTuple colSequence = new HTuple();
            try
            {
                double[] points = pointList.ToArray();

                HOperatorSet.GenImageConst(out Image, "real", width, height); //行列互换一下
                HOperatorSet.GetRegionPoints(Image, out rowSequence, out colSequence);
                HOperatorSet.SetGrayval(Image, rowSequence, colSequence, points);
            }
            catch (Exception)
            {
                throw new Exception("点云转换失败");
            }

            return true;
        }

        #endregion

        #region 保存图片

        private static readonly object obj1 = new object();
        private static readonly object obj2 = new object();
        public static bool SaveImageWithBarCode(HObject image, string dirPath, string ImagName)
        {
            lock (obj1)
            {
                bool ret = true;
                try
                {
                    if (!FileUtils.IsExistDirectory(dirPath))
                    {
                        FileUtils.CreateDirectory(dirPath);
                    }
                    HOperatorSet.WriteImage(image, "bmp", 0, dirPath + "\\" + ImagName + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss"));//+ DateTime.Now.ToString("_HH_mm_ss")yyyy-MM-dd HH:mm:ss
                }
                catch (Exception exc)
                {
                    ret = false;
                }
                return ret;
            }

        }

        public static bool SaveImageLaser(HObject image, string dirPath, string ImgName)
        {
            lock (obj2)
            {
                bool ret = true;
                try
                {
                    if (!FileUtils.IsExistDirectory(dirPath))
                    {
                        FileUtils.CreateDirectory(dirPath);
                    }
                    HOperatorSet.WriteImage(image, "tiff", 0, dirPath + "\\" + ImgName);// + DateTime.Now.ToString("_HH_mm_ss")
                }
                catch (Exception exc)
                {
                    ret = false;
                }
                return ret;
            }
        }
        #endregion

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="strLog"></param>
        /// <param name="fileName"></param>
        public static void WriteLogToTxt(string strLog, string fileName, string station)
        {
            try
            {
                String System_Now_Time = null;
                String File_Create_Time = null;

                System_Now_Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                File_Create_Time = DateTime.Now.ToString("yyyyMMdd");
                string logDocument = $"{station}_{File_Create_Time}.csv";

                string str = Process.GetCurrentProcess().MainModule.FileName;
                string logFilePath = str.Substring(0, str.LastIndexOf("\\")) + "\\ALog\\" + fileName;

                if (!Directory.Exists(logFilePath))
                {
                    Directory.CreateDirectory(logFilePath);
                }
                logFilePath = logFilePath + "//" + logDocument;

                if (!File.Exists(logFilePath))
                {
                    File.AppendAllText(logFilePath, $"Time,Station,StationInfo,CT,{Environment.NewLine}", Encoding.GetEncoding(0));
                }

                File.AppendAllText(logFilePath, System_Now_Time + "," + strLog + Environment.NewLine, Encoding.GetEncoding(0));

            }
            catch (Exception ex)
            {
                Common.AppendUiLog.Log(ex.StackTrace, LogType.Error);
                //MessageBox.Show("写日志文件失败！\r\n", "写日志文件失败,点击确定重试一次，点击取消放弃保存！", MessageBoxButtons.OKCancel);
            }

        }
        #endregion


        public static bool ChangeProjectExvent()
        {

            var changeRet = true;
            Dlg_Notice dlg_Notice = new Dlg_Notice();
            dlg_Notice.TopMost = true;
            dlg_Notice.Show();
            //Application.DoEvents();
            //切视觉算法
            //dlg_Notice.UpdateStep(5, "正在切换算法...", true);
            bool ret = false;
            ret = true;

            //ret = LoadSlp(Common.CurProType);
            //if (ret)
            //    dlg_Notice.UpdateStep(30, "切换算法完成", ret);
            //else
            //    dlg_Notice.UpdateStep(30, "切换算法失败,文件不存在", ret);

            //dlg_Notice.UpdateStep(35, "正在切换激光参数...", true);
            //切换激光参数
            //ret = ChangeLaserParam(Common.CurProType);
            changeRet &= ret;
            //if (ret)
            //    dlg_Notice.UpdateStep(75, "切换激光参数完成", ret);
            //else
            //    dlg_Notice.UpdateStep(75, "切换激光参数失败", ret);

            dlg_Notice.UpdateStep(80, "正在切换光源项目源...", true);
            //切换光源项目源
            ret = Machine.ImageLightInit(Common.CurProType);
            changeRet &= ret;
            if (ret)
                dlg_Notice.UpdateStep(100, "切换光源项目源完成", ret);
            else
                dlg_Notice.UpdateStep(100, "切换光源项目源失败", ret);

            if (changeRet)
                dlg_Notice.Close();
            else
            {
                dlg_Notice.FormBorderStyle = FormBorderStyle.FixedSingle;

                dlg_Notice.lbl_NoticeTxt.Text = "参数修改失败";
                dlg_Notice.lbl_HandleTxt.Text = "请查看失败项";
            }


            Common.AppendUiLog.Log($"切换产品类型={Common.CurProType},算法切换Slp, 光源切换结果={ret}", LogType.Alert);
            return changeRet;
        }

        public static bool LoadSlp(string ProType, string ProjectName)
        {
            var slpPath = Application.StartupPath + "\\SLP\\" + ProjectName + ".slp";
            if (File.Exists(slpPath))
                Vision.LoadSlp(slpPath);
            else
                return false;

            return true;
        }


        public static void LoadProTypeParam()
        {
            Dictionary<string, string> dic;
            dic = INIUtils.GetAllKeyValues(Common.Section_ProductTypeConfig, Common.ProTypeIniPath);
            if (Common.ProductTypeMeasureItemEnableList.Count > 0)
                Common.CurProType = GetIniValue(dic, "CurProductType", $"{Common.ProductTypeMeasureItemEnableList[0].ProductType}", Common.ProTypeIniPath, Common.Section_ProductTypeConfig);
            else
                Common.CurProType = GetIniValue(dic, "CurProductType", $"{Common.ProductType}", Common.ProTypeIniPath, Common.Section_ProductTypeConfig);

            dic = INIUtils.GetAllKeyValues(Common.Section_MeasureItems, Common.ProTypeIniPath);
            var DefaultMeasureItemsStr = GetIniValue(dic, "DefaultMeasureItems", string.Join(",", Common.DefaultMeasureItems), Common.ProTypeIniPath, Common.Section_MeasureItems);
            if (!string.IsNullOrEmpty(DefaultMeasureItemsStr))
                Common.DefaultMeasureItems = DefaultMeasureItemsStr.Split(',').ToList();
        }
        public static string GetIniValue(Dictionary<string, string> dic, string Key, string defaultValue, string path, string Section = "AFMT")
        {
            dic.TryGetValue(Key, out string Value);
            if (Value == null)
            {
                INIUtils.Write(Section, Key, defaultValue, path);
                Value = defaultValue;
            }
            return Value;
        }

        public static void WriteCurProTypeIni(string value)
        {
            INIUtils.Write(Common.Section_ProductTypeConfig, "CurProductType", value, Common.ProTypeIniPath);
        }

        public static void LoadProTypeMeasureItemEnableConfig()
        {
            try
            {
                Common.ProductTypeMeasureItemEnableList.Clear();
                if (!File.Exists(Common.ProTypeCsvPath))
                {
                    Common.ProductTypeMeasureItemEnableList = new List<ProductTypeMeasureItemEnable>
                    {
                        NewDefaultProTypeMeasureItemEnable($"Block", Common.DefaultMeasureItems),//以实际项目自由添加测量种类默认
                        NewDefaultProTypeMeasureItemEnable($"Product", Common.DefaultMeasureItems)
                    };

                    //todo sAVE
                    bool isHeader = false;
                    string ProTypeHeader = "";
                    string Values = "";
                    foreach (var productTypeMeasureItemEnable in Common.ProductTypeMeasureItemEnableList)
                    {
                        string value = "";
                        if (!isHeader)
                            ProTypeHeader += $"产品类型,";
                        value += $"{productTypeMeasureItemEnable.ProductType},";
                        foreach (var measureItemEnable in productTypeMeasureItemEnable.MeasureItemEnableDic)
                        {
                            if (!isHeader)
                                ProTypeHeader += $"{measureItemEnable.Key},";
                            value += $"{measureItemEnable.Value},";
                        }
                        if (!isHeader)
                            ProTypeHeader += Environment.NewLine;
                        isHeader = true;
                        Values += value + Environment.NewLine;
                    }
                    FileUtils.AppendText(Common.ProTypeCsvPath, ProTypeHeader);
                    FileUtils.AppendText(Common.ProTypeCsvPath, Values);
                }
                else
                {
                    var dt = FileUtils.OpenCSV(Common.ProTypeCsvPath);
                    List<string> MeasureItems = new List<string>();
                    foreach (DataColumn col in dt.Columns)
                    {
                        if (col.ColumnName.Equals("产品类型"))
                            continue;
                        MeasureItems.Add(col.ColumnName);
                    }
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        var name = "";
                        var NewProTypeMeasureItemsEnable = NewDefaultProTypeMeasureItemEnable(name, MeasureItems);
                        for (int j = 0; j < dt.Columns.Count; j++)
                        {
                            if (j == 0)
                            {
                                name = dt.Rows[i][j].ToString();
                                NewProTypeMeasureItemsEnable.ProductType = name;
                            }
                            else
                            {
                                DataColumn col = dt.Columns[j];
                                var key = col.ColumnName;
                                var value = false;
                                if (string.IsNullOrEmpty(dt.Rows[i][j].ToString()))
                                {
                                    value = false;
                                }
                                else
                                    value = bool.Parse(dt.Rows[i][j].ToString());

                                if (NewProTypeMeasureItemsEnable.MeasureItemEnableDic.ContainsKey(key))
                                    NewProTypeMeasureItemsEnable.MeasureItemEnableDic[key] = value;
                            }
                        }
                        var findItem = Common.ProductTypeMeasureItemEnableList.Find(x => x.ProductType == name);
                        if (findItem == null)
                            Common.ProductTypeMeasureItemEnableList.Add(NewProTypeMeasureItemsEnable);
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }
        private static ProductTypeMeasureItemEnable NewDefaultProTypeMeasureItemEnable(string Name, List<string> defaultMeasureItems)
        {
            ProductTypeMeasureItemEnable productTypeMeasureItemEnable = new ProductTypeMeasureItemEnable() { ProductType = Name };
            foreach (var item in defaultMeasureItems)
            {
                if (!productTypeMeasureItemEnable.MeasureItemEnableDic.ContainsKey(item))
                    productTypeMeasureItemEnable.MeasureItemEnableDic.Add(item, true);
            }
            return productTypeMeasureItemEnable;
        }


        public static void ReadCSVFile()
        {
            try
            {
                //读取点检文件
                string[] fileNames_book = FileUtils.GetFileNames(Common.pointCheckPath);
                foreach (string fileName in fileNames_book)
                {
                    string temp = fileName.ToLower();//统一转换为小写

                    if (Common.CurProType == "Product")
                    {
                        if (temp.Contains("grr_standard_product.csv"))
                        {
                            Common.GRRPointCheckTable = FileUtils.OpenCSV(temp);
                        }
                    }
                }
            }
            catch
            {
                //MessageBox.Show("读取点检文件失败!");
                Common.AppendUiLog.Log("读取点检文件失败!", LogType.Error);
            }
        }

        public static int GetRandomSeed()
        {
            byte[] bytes = new byte[4];
            System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
            rng.GetBytes(bytes);
            return BitConverter.ToInt32(bytes, 0);
        }

        public static double GetRandom()
        {
            Random r1 = new Random(GetRandomSeed());
            Random r2 = new Random(GetRandomSeed());
            double numb;

            do
            {
                if (r1.NextDouble() - r2.NextDouble() > 0.5 || r1.NextDouble() - r2.NextDouble() < -0.5)
                {
                    numb = r1.NextDouble() - r2.NextDouble();
                    return numb;
                }
                else
                {
                    continue;
                }
            } while (true);

        }

        public static double GetRandomDouble(double min, double max)
        {
            Random random = new Random();

            if (min > max)
            {
                throw new ArgumentException("Min value should be less than or equal to Max value.");
            }

            // 生成[0, 1)范围内的随机数
            double randomNumber = random.NextDouble();

            // 将[0, 1)范围内的随机数转换为[min, max)范围内的随机数
            double randomInRange = randomNumber * (max - min) + min;

            return randomInRange;
        }


        //和PLC信号通信的线程
        public static void ThreadMethod_ScanOmronPLC()
        {
            try
            {
                while (MachineStatusManager.CurrentMachineStatus != MachineStatus.Quit)
                {
                    if (Common.opreateResult_Isconnect.IsSuccess)
                    {
                        try
                        {
                            var abc = Common.PLCAdr.DicInput;
                            foreach (var item in Common.PLCAdr.DicInput)
                            {
                                Common.PLCAdr.DicInPutValue[item.Key] = Common.OmronPLC.ReadBool(item.Value).Content;
                            }
                            PlcHeart = Common.PLCAdr.DicInPutValue[PLCInPut.心跳];
                            Common.IsClearModel = Common.PLCAdr.DicInPutValue[PLCInPut.清料模式];
                            //if (Common.PLCAdr.DicInPutValue[PLCInPut.异常状态])
                            //{
                            //    MachineStatusManager.CurrentMachineStatus = MachineStatus.Alarm;
                            //}
                        }
                        catch (Exception ex)
                        {
                            Common.AppendUiLog.Log($"扫描PLC信号异常" + ex.ToString(), LogType.Error);
                        }
                    }
                    Thread.Sleep(100);
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }

        public static void ThreadMethod_Alarm()
        {
            var time = DateTime.Now;
            string CSVDataDirectory = $"{Common.dataSavePath}\\{Common.ProjectName}\\{time:yyyy-MM}\\{Common.CurProType} Data\\{time:yyyy-MM-dd}";
            if (!Directory.Exists(CSVDataDirectory))
            {
                Directory.CreateDirectory(CSVDataDirectory);
            }
            string fullPath = $"{CSVDataDirectory}\\报警上传记录" + DateTime.Now.ToString("yyyy-MM-dd") + ".csv";
            string starttime = string.Empty;
            string endtime = string.Empty;
            string startTime = string.Empty;
            while (MachineStatusManager.CurrentMachineStatus != MachineStatus.Quit)
            {

                if (Common.opreateResult_Isconnect.IsSuccess)
                {
                    try
                    {
                        //bool alarmFlag = Common.Alarm_PLC轻报警;

                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.下料机械手真空1报警], "下料机械手真空1报警", "10010509001", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.下料机械手真空2报警], "下料机械手真空2报警", "10010509002", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.爪1有产品无测试结果], "爪1有产品无测试结果", "10010509003", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.爪2有产品无测试结果], "爪2有产品无测试结果", "10010509004", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.爪1有测试结果无产品], "爪1有测试结果无产品", "10010509005", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.爪2有测试结果无产品], "爪1有测试结果无产品", "10010509006", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.机械手爪1升降气管不在原点], "机械手爪1升降气管不在原点", "10010509007", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.机械手爪1升降气管不在动点], "机械手爪1升降气管不在动点", "10010509008", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.机械手爪2升降气管不在原点], "机械手爪2升降气管不在原点", "10010509009", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.机械手爪2升降气管不在动点], "机械手爪2升降气管不在动点", "10010509010", ref alarmFlag, startTime, fullPath);

                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.Tray盘防呆感应器报警], "Tray盘防呆感应器报警", "10010510001", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.Tray盘到位感应器报警], "Tray盘到位感应器报警", "10010510002", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.Tray盘缓存感应器报警], "Tray盘缓存感应器报警", "10010510003", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.入料口感应信号异常], "入料口感应信号异常", "10010510004", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.顶升Tray限位感应器报警], "顶升Tray限位感应器报警", "10010510005", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.Tray盘数量高度限位感应器报警], "Tray盘数量高度限位感应器报警", "10010510006", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.料仓安全光栅报警], "料仓安全光栅报警", "10010510007", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.空Tray料盘分盘气缸1不在动点], "空Tray料盘分盘气缸1不在动点", "10010510008", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.空Tray料盘分盘气缸1不在原点], "空Tray料盘分盘气缸1不在原点", "10010510009", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.空Tray料盘分盘气缸2不在动点], "空Tray料盘分盘气缸2不在动点", "10010510010", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.空Tray料盘分盘气缸2不在原点], "空Tray料盘分盘气缸2不在原点", "10010510011", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.OK料盘定位气缸不在动点], "OK料盘定位气缸不在动点", "10010510012", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.OK料盘定位气缸不在原点], "OK料盘定位气缸不在原点", "10010510013", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.NG料盘定位气缸不在动点], "NG料盘定位气缸不在动点", "10010510014", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.NG料盘定位气缸不在原点], "NG料盘定位气缸不在原点", "10010510015", ref alarmFlag, startTime, fullPath);
                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.上料皮带拍照超时], "上料皮带拍照超时", "10010510016", ref alarmFlag, startTime, fullPath);

                        ////HandleAlarm(Common.PLCAdr.DicInPutValue[PLCInPut.上料机械手真空报警], "上料机械手真空报警", "10010502001", ref alarmFlag, startTime, fullPath);

                        //Common.Alarm_PLC轻报警 = alarmFlag;

                    }
                    catch
                    {

                    }
                    Thread.Sleep(3000);
                }
            }

        }

    
    public static void HandleAlarm(bool alarmCondition, string alarmDescription, string alarmCode, ref bool alarmFlag, string startTime, string fullPath)
    {
        if (alarmCondition && !alarmFlag)
        {
            startTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            alarmFlag = true;
            var str = $"{alarmDescription}, 开始时间：{startTime}, 报警代码：{alarmCode}";
            FileUtils.AppendText(fullPath, str + "\r\n");
        }
        else if (!alarmCondition && alarmFlag)
        {
            var endTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            alarmFlag = false;
            var str = $"{alarmDescription}, 结束时间：{endTime}, 报警代码：{alarmCode}";
            FileUtils.AppendText(fullPath, str + "\r\n");

            if (Common.BP_UPMES)
            {
                Common.SwMes.StatusDataUpload(STATUSCODE.报警中, startTime, endTime, alarmCode);
            }
        }
    }

    private static bool _PlcIsOnline;

    public static bool PlcIsOnline
    {
        get { return _PlcIsOnline; }
        set
        {
            if (_PlcIsOnline != value)
            {
                _PlcIsOnline = value;
                Frm_Main.Instance.Invoke(new Action(() =>
                {
                    Frm_Main.Instance.label3.Text = value ? "PLC连接成功" : "PLC连接失败";
                    Frm_Main.Instance.label3.BackColor = value ? Color.Green : Color.Red;
                }));
            }
        }
    }

    public static void ThreadMethod_PLCHeart()
    {
        while (true)
        {
            if (Common.opreateResult_Isconnect.IsSuccess)
            {
                PlcIsOnline = true;
                Common.OmronPLC.Write(Common.PLCAdr.DicOutPutBool[StationLogic.PLCOutPutBool.心跳], true);
                Thread.Sleep(1000);
                Common.OmronPLC.Write(Common.PLCAdr.DicOutPutBool[StationLogic.PLCOutPutBool.心跳], false);
                Thread.Sleep(1000);
            }
            else
            {
                PlcIsOnline = false;
            }
            Thread.Sleep(0);
        }

    }


    private static bool _PlcHeart;

    public static bool PlcHeart
    {
        get { return _PlcHeart; }
        set
        {
            if (_PlcHeart != value)
            {
                _PlcHeart = value;
                Frm_Main.Instance.Invoke(new Action(() =>
                {
                    Frm_Main.Instance.label4.BackColor = value ? Color.Green : Color.Gray;
                }));
            }
        }
    }
}
}

